﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2010-09-21 17:30:06Z</CreationDate>
</File>
*/
#endregion

#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
#else
using System.Windows;
using System.Windows.Data;
#endif

namespace Outcoder.ComponentModel
{
	public class DataContextChangedListener
	{
		static readonly DependencyProperty DataContextProperty
			= DependencyProperty.RegisterAttached(
				"DataContextProperty",
				typeof(object),
				typeof(FrameworkElement),
				new PropertyMetadata(
					new PropertyChangedCallback(OnDataContextChanged)));

		static readonly DependencyProperty HandlersProperty
			= DependencyProperty.RegisterAttached(
				"HandlersProperty",
				typeof(PropertyChangedCallback),
				typeof(FrameworkElement),
				new PropertyMetadata(
					(object)((PropertyChangedCallback)(delegate { }))));

		public static void Subscribe(
			FrameworkElement element, PropertyChangedCallback handler)
		{
			ArgumentValidator.AssertNotNull(element, "element");
			ArgumentValidator.AssertNotNull(handler, "handler");

			PropertyChangedCallback handlers
				= (PropertyChangedCallback)element.GetValue(HandlersProperty);

			handlers += handler;

			element.SetValue(HandlersProperty, handlers);
#if !NETFX_CORE
			if (element.GetBindingExpression(DataContextProperty) == null)
			{
				element.SetBinding(DataContextProperty, new Binding());
			}
#endif
		}

		public static void Unsubscribe(
			FrameworkElement element, PropertyChangedCallback handler)
		{
			ArgumentValidator.AssertNotNull(element, "element");
			ArgumentValidator.AssertNotNull(handler, "handler");

			PropertyChangedCallback handlers
				= (PropertyChangedCallback)element.GetValue(HandlersProperty);

			handlers -= handler;
			element.SetValue(HandlersProperty, handlers);
		}

		static void OnDataContextChanged(
			DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			FrameworkElement element = (FrameworkElement)d;
			PropertyChangedCallback handlers
				= (PropertyChangedCallback)element.GetValue(HandlersProperty);
			var tempEvent = handlers;
			if (tempEvent != null)
			{
				tempEvent(d, e);
			}
		}
	}
}